﻿//IMarketDataSerializer.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.Storages
{
	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Linq;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.BusinessEntities;

	internal interface IMarketDataSerializer<TData, TMetaInfo>
		where TMetaInfo : MetaInfo<TMetaInfo>
	{
		byte[] Serialize(IEnumerable<TData> data, MetaInfo<TMetaInfo> metaInfo);

		IEnumerableEx<TData> Deserialize(byte[] rawData, DateTime date, MetaInfo<TMetaInfo> metaInfo);
	}

	internal abstract class MarketDataSerializer<TData, TMetaInfo> : IMarketDataSerializer<TData, TMetaInfo>
		where TMetaInfo : MetaInfo<TMetaInfo>
	{
		protected MarketDataSerializer(Security security, int dataSize)
		{
			if (security == null)
				throw new ArgumentNullException("security");

			Security = security;
			DataSize = dataSize;
		}

		protected Security Security { get; private set; }
		protected int DataSize { get; private set; }

		byte[] IMarketDataSerializer<TData, TMetaInfo>.Serialize(IEnumerable<TData> data, MetaInfo<TMetaInfo> metaInfo)
		{
			var array = new List<bool>(DataSize * data.Count() * 2);

			OnSave(array, data, (TMetaInfo)metaInfo);

			return new BitArray(array.ToArray()).To<byte[]>();
		}

		IEnumerableEx<TData> IMarketDataSerializer<TData, TMetaInfo>.Deserialize(byte[] rawData, DateTime date, MetaInfo<TMetaInfo> metaInfo)
		{
			return new SimpleEnumerable<TData>(() => GetEnumerator(rawData, date, metaInfo)).ToEx(metaInfo.Count);
		}

		private IMarketDataEnumerator<TData> GetEnumerator(byte[] rawData, DateTime date, MetaInfo<TMetaInfo> metaInfo)
		{
			return new MarketDataEnumerator<TData, TMetaInfo>(this, date, new OptimizedBitArrayReader(rawData), (TMetaInfo)metaInfo);
		}

		protected abstract void OnSave(List<bool> bits, IEnumerable<TData> data, TMetaInfo metaInfo);
		public abstract TData MoveNext(MarketDataEnumerator<TData, TMetaInfo> enumerator);
	}
}